/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mycompany.managedbean;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.LazyDataModel;


/**
 *
 * @author Muharrem Tigdemir <Muharrem Tigdemir at muharremtigdemir.com>
 */
@ManagedBean
@ViewScoped
public class TableBean extends Connector implements Serializable {

    private List<DataObject> values;
    private DataObjectModel model;
    private LazyDataModel<DataObject> lazymodel;
    private List<ColumnModel> columns;
    private DataObject selectedDataObject;
    private Integer totalRowCount;
    @ManagedProperty(value = "#{mainController}")
    private MainController controller;
    public static int uniqueID = 0;
    private String collectionName = new String();
    private String databaseName = new String();

    public TableBean() {
        //lazymodel = new LazyDataObjectModel();
    }

    public void loadDatas(int first, int pageSize) {
        if (!collectionName.equals("") && !databaseName.equals("")) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Collection Listed", collectionName);
            FacesContext.getCurrentInstance().addMessage(null, message);

            values = new ArrayList<DataObject>();
            columns = new ArrayList<ColumnModel>();

            database = client.getDB(databaseName);
            DBCollection collectionArray = database.getCollection(collectionName);
            List<DBObject> objList = collectionArray.find().skip(first).limit(pageSize).toArray();
            setTotalRowCount(collectionArray.find().count());
            int property = 0;
            for (DBObject dBObject : objList) {
                uniqueID++;
                HashMap<String, String> map = (HashMap<String, String>) dBObject.toMap();
                DataObject nodeObj = new DataObject();
                HashMap<String, String> newObj = new HashMap<String, String>();

                for (Map.Entry mapEntry : map.entrySet()) {

                    if (!isColumnExists(mapEntry.getKey().toString())) {
                        /*Create New Column*/
                        ColumnModel model = new ColumnModel(mapEntry.getKey().toString(), mapEntry.getKey().toString());
                        columns.add(model);
                        property++;
                    }

                    newObj.put(mapEntry.getKey().toString(), mapEntry.getValue().toString());
                    nodeObj.setMultimap(newObj);
                    nodeObj.setUniqueID(uniqueID);
                    nodeObj.setDbObject(dBObject);
                    //Set Pretty JSON Object
                    Gson gson = new GsonBuilder().setPrettyPrinting().create();
                    String json = gson.toJson(dBObject);
                    nodeObj.setOrjinalObject(json);
                }
                /*Added Column Map to DataObject*/
                values.add(nodeObj);
            }
           System.out.println(values.toString());
            model = new DataObjectModel(values);
        }
    }

    public void generateTable() {
        collectionName = controller.getSelectedNode().getData().toString();
        databaseName = controller.getSelectedNode().getParent().toString();
    }

    public void generateTable2() {
        if (!collectionName.equals("") && !databaseName.equals("")) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Collection Listed", collectionName);
            FacesContext.getCurrentInstance().addMessage(null, message);

            values = new ArrayList<DataObject>();
            columns = new ArrayList<ColumnModel>();

            database = client.getDB(databaseName);
            DBCollection collectionArray = database.getCollection(collectionName);
            List<DBObject> objList = collectionArray.find().toArray();
            setTotalRowCount(collectionArray.find().count());
            int property = 0;
            for (DBObject dBObject : objList) {
                uniqueID++;
                HashMap<String, String> map = (HashMap<String, String>) dBObject.toMap();
                DataObject nodeObj = new DataObject();
                HashMap<String, String> newObj = new HashMap<String, String>();

                for (Map.Entry mapEntry : map.entrySet()) {

                    if (!isColumnExists(mapEntry.getKey().toString())) {
                        /*Create New Column*/
                        ColumnModel model = new ColumnModel(mapEntry.getKey().toString(), mapEntry.getKey().toString());
                        columns.add(model);
                        property++;
                    }

                    newObj.put(mapEntry.getKey().toString(), mapEntry.getValue().toString());
                    nodeObj.setMultimap(newObj);
                    nodeObj.setUniqueID(uniqueID);
                    nodeObj.setDbObject(dBObject);
                    //Set Pretty JSON Object
                    Gson gson = new GsonBuilder().setPrettyPrinting().create();
                    String json = gson.toJson(dBObject);
                    nodeObj.setOrjinalObject(json);
                }
                /*Added Column Map to DataObject*/
                values.add(nodeObj);
            }

            model = new DataObjectModel(values);
        }
    }

    public List<ColumnModel> getColumns() {
        return columns;
    }

    public void setColumns(List<ColumnModel> columns) {
        this.columns = columns;
    }

    public List<DataObject> getValues() {
        return values;
    }

    public void setValues(List<DataObject> values) {
        this.values = values;
    }

    public Integer getTotalRowCount() {
        return totalRowCount;
    }

    public void setTotalRowCount(Integer totalRowCount) {
        this.totalRowCount = totalRowCount;
    }

    public DataObject getSelectedDataObject() {
        return selectedDataObject;
    }

    public void setSelectedDataObject(DataObject selectedDataObject) {
        this.selectedDataObject = selectedDataObject;
    }

    public MainController getController() {
        return controller;
    }

    public void setController(MainController controller) {
        this.controller = controller;
    }

    public DataObjectModel getModel() {
        return model;
    }

    public void setModel(DataObjectModel model) {
        this.model = model;
    }

    public boolean isColumnExists(Object compare) {
        for (ColumnModel columnModel : columns) {
            if (columnModel.getHeader().equals(compare)) {
                return true;
            }
        }
        return false;
    }

    public void updateObject() {
        database = client.getDB(databaseName);
    }

    public void test() {
        System.out.println("Test Action");
    }

    public String getCollectionName() {
        return collectionName;
    }

    public void setCollectionName(String collectionName) {
        this.collectionName = collectionName;
    }

    public String getDatabaseName() {
        return databaseName;
    }

    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }

    public void insertObject() {
        System.out.println(collectionName + " - " + databaseName);

        database = client.getDB(databaseName);

        DBCollection coll = database.getCollection(collectionName);
        BasicDBObject doc = new BasicDBObject("name", "MongoDB").
                append("type", "database").
                append("count", 1);
        coll.insert(doc);
    }

    public void onRowSelect(SelectEvent event) {
        selectedDataObject = (DataObject) event.getObject();
    }

    public LazyDataModel<DataObject> getLazymodel() {
        return lazymodel;
    }

    public void setLazymodel(LazyDataModel<DataObject> lazymodel) {
        this.lazymodel = lazymodel;
    }

    public void deleteDataObject() {

        database = client.getDB(databaseName);

        DBCollection coll = database.getCollection(collectionName);
        totalRowCount--;
        coll.remove(selectedDataObject.getDbObject());

        //Remove From Datatable
        values.remove(selectedDataObject);
    }

    /*Column Model*/
    static public class ColumnModel implements Serializable {

        private String header;
        private String property;

        public ColumnModel(String header, String property) {
            this.header = header;
            this.property = property;
        }

        public String getHeader() {
            return header;
        }

        public String getProperty() {
            return property;
        }
    }
}
